//! Error types for the ComfyUI SDK

use thiserror::Error;

/// Result type alias for ComfyUI SDK operations
pub type Result<T> = std::result::Result<T, ComfyUIError>;

/// Main error type for ComfyUI SDK
#[derive(Error, Debug)]
pub enum ComfyUIError {
    /// HTTP request errors
    #[error("HTTP error: {0}")]
    Http(#[from] reqwest::Error),

    /// WebSocket errors
    #[error("WebSocket error: {0}")]
    WebSocket(#[from] tokio_tungstenite::tungstenite::Error),

    /// JSON serialization/deserialization errors
    #[error("JSON error: {0}")]
    Json(#[from] serde_json::Error),

    /// URL parsing errors
    #[error("URL error: {0}")]
    Url(#[from] url::ParseError),

    /// Template validation errors
    #[error("Template validation error: {0}")]
    TemplateValidation(String),

    /// Parameter validation errors
    #[error("Parameter validation error: {0}")]
    ParameterValidation(String),

    /// Connection errors
    #[error("Connection error: {0}")]
    Connection(String),

    /// Execution errors
    #[error("Execution error: {0}")]
    Execution(String),

    /// Timeout errors
    #[error("Timeout error: {0}")]
    Timeout(String),

    /// Generic errors
    #[error("Error: {0}")]
    Generic(String),

    /// IO errors
    #[error("IO error: {0}")]
    Io(#[from] std::io::Error),
}

impl ComfyUIError {
    /// Create a new generic error
    pub fn new(message: impl Into<String>) -> Self {
        Self::Generic(message.into())
    }

    /// Create a new template validation error
    pub fn template_validation(message: impl Into<String>) -> Self {
        Self::TemplateValidation(message.into())
    }

    /// Create a new parameter validation error
    pub fn parameter_validation(message: impl Into<String>) -> Self {
        Self::ParameterValidation(message.into())
    }

    /// Create a new connection error
    pub fn connection(message: impl Into<String>) -> Self {
        Self::Connection(message.into())
    }

    /// Create a new execution error
    pub fn execution(message: impl Into<String>) -> Self {
        Self::Execution(message.into())
    }

    /// Create a new timeout error
    pub fn timeout(message: impl Into<String>) -> Self {
        Self::Timeout(message.into())
    }
}
